package ${properties.daoPkgName};

import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

public class BaseDAO extends HibernateDaoSupport {

	public void evict(Object obj) {
		getHibernateTemplate().evict(obj);
	}

	/**
	 * 通过hql查询查询实体
	 * 
	 * @param hql
	 * @return 返回执行结果实体List
	 */
	public List<?> find(final String hql) {
		return getHibernateTemplate().find(hql);
	}

	/**
	 * 通过hql和参数查询实体
	 * 
	 * @param hql
	 * @param params Object[]
	 * @return 返回执行结果实体List
	 */
	public List<?> find(final String hql, Object[] params) {
		return getHibernateTemplate().find(hql, params);
	}
	
	/**
	 * 通过hql和参数查询数据
	 * 
	 * @param hql
	 * @param params List<?>
	 * @param firstResult 起始记录点
	 * @param maxResults 返回最大记录数
	 * @return 返回执行结果List
	 */
	public List<?> find(final String hql, final List<?> params,final int firstResult, final int maxResults) {
		return (List<?>) getHibernateTemplate().executeFind(new HibernateCallback() {
			public Object doInHibernate(Session session) throws HibernateException, SQLException {
				Query query = session.createQuery(hql);
				if (firstResult != -1)
					query.setFirstResult(firstResult);
				if (maxResults != -1)
					query.setMaxResults(maxResults);
				if (params != null)
					for (int i = 0; i < params.size(); i++)
						query.setParameter(i, params.get(i));
				return query.list();
			}
		});
	}	

	/**
	 * 通过普通sql查询数据
	 * 
	 * @param sql
	 * @return 返回执行结果List（包含Object[]数组）
	 */
	public List<?> findBySql(final String sql) {
		return findBySql(sql, null);
	}

	/**
	 * 通过普通sql和参数查询数据
	 * 
	 * @param sql
	 * @param params List<?>
	 * @return 返回执行结果List（包含Object[]数组）
	 */
	public List<?> findBySql(final String sql, final List<?> params) {
		return findBySql(sql, params,-1, -1);
	}

	/**
	 * 通过普通sql和参数查询数据
	 * 
	 * @param sql
	 * @param params List<?>
	 * @param firstResult 起始记录点
	 * @param maxResults 返回最大记录数
	 * @return 返回执行结果List（包含Object[]数组）
	 */
	public List<?> findBySql(final String sql, final List<?> params, final int firstResult, final int maxResults) {
		return (List<?>) getHibernateTemplate().executeFind(new HibernateCallback() {

			public Object doInHibernate(Session session) throws HibernateException, SQLException {
				Query query = session.createSQLQuery(sql);
				if (firstResult != -1)
					query.setFirstResult(firstResult);
				if (maxResults != -1)
					query.setMaxResults(maxResults);
				if (params != null)
					for (int i = 0; i < params.size(); i++)
						query.setParameter(i, params.get(i));	
				return query.list();				
			}
		});
	}
	
	/**
	 * 通过hql查询数据集大小
	 * 
	 * @param hql
	 * @param params
	 * @return 数据集大小
	 */
	public int count(final String hql) {
		return count(hql, null);
	}
	
	
	/**
	 * 通过hql和参数查询数据集大小
	 * 
	 * @param hql
	 * @param params
	 * @return 数据集大小
	 */
	public int count(final String hql, final List<?> params) {
		Long count = (Long) (getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session session) throws HibernateException, SQLException {
				String countHql = "select count(*) "+hql.substring(hql.toLowerCase().indexOf("from"));
				Query query = session.createQuery(countHql);
				if (params != null)
					for (int i = 0; i < params.size(); i++)
						query.setParameter(i, params.get(i));
				return ((Long) query.uniqueResult()).longValue();
			}
		}));
		return count.intValue();
	}

	/**
	 * 通过普通sql查询数据集大小
	 * 
	 * @param sql
	 * @param params
	 * @return 数据集大小
	 */
	public int countBySql(final String sql) {
		return countBySql(sql, null);
	}

	/**
	 * 通过普通sql和参数查询数据集大小
	 * 
	 * @param sql
	 * @param params
	 * @return 数据集大小
	 */
	public int countBySql(final String sql, final List<?> params) {
		Long count = (Long) (getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session session) throws HibernateException, SQLException {
				Query query = session.createSQLQuery("select count(0) from (" + sql + ")");
				if (params != null)
					for (int i = 0; i < params.size(); i++)
						query.setParameter(i, params.get(i));
				return ((BigDecimal) query.uniqueResult()).longValue();
			}
		}));
		return count.intValue();
	}

	/**
	 * 通过hql执行数据更新删除操作
	 * 
	 * @param hql
	 * @return 返回执行结果
	 */
	public int excute(final String hql) {
		return excute(hql, null);
	}

	/**
	 * 通过hql和参数执行数据更新删除操作
	 * 
	 * @param hql
	 * @param params List<?>
	 * @return 返回执行结果
	 */
	public int excute(final String hql, final List<?> params) {
		ArrayList<List<?>> paramsList = new ArrayList<List<?>>(0);
		paramsList.add(params);
		List<Integer> result = excuteBatch(hql, paramsList);
		return result.get(0);
	}

	/**
	 * 通过普通hql和参数集合执行批量数据更新删除操作
	 * 
	 * @param hql
	 * @param paramsList List<List<?>>
	 * @return 返回执行结果的Integer集合
	 */
	@SuppressWarnings("unchecked")
	public List<Integer> excuteBatch(final String hql, final List<List<?>> paramsList) {
		return (List<Integer>) getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session session) throws HibernateException, SQLException {
				List<Integer> result = new ArrayList<Integer>(0);
				if (paramsList != null)
					for (int i = 0; i < paramsList.size(); i++) {
						Query query = session.createQuery(hql);
						List<?> params = paramsList.get(i);
						if (params != null)
							for (int j = 0; j < params.size(); j++)
								query.setParameter(j, params.get(j));
						result.add(query.executeUpdate());
					}
				return result;
			}
		});
	}

	/**
	 * 通过普通sql执行数据库更新和删除操作
	 * 
	 * @param sql
	 * @return 返回执行结果
	 */
	public int excuteBySql(final String sql) {
		return excuteBySql(sql, null);
	}

	/**
	 * 通过普通sql和参数执行数据库更新和删除操作
	 * 
	 * @param sql
	 * @param params List<?>
	 * @return 返回执行结果
	 */
	public int excuteBySql(final String sql, final List<?> params) {
		ArrayList<List<?>> paramsList = new ArrayList<List<?>>(0);
		paramsList.add(params);
		List<Integer> result = excuteBatchBySql(sql, paramsList);
		return result.get(0);
	}

	/**
	 * 通过普通sql和参数集合执行批量数据库更新删除操作
	 * 
	 * @param sql
	 * @param paramsList List<List<?>>
	 * @return 返回执行结果的Integer集合
	 */
	@SuppressWarnings("unchecked")
	public List<Integer> excuteBatchBySql(final String sql, final List<List<?>> paramsList) {
		return (List<Integer>) getHibernateTemplate().execute(new HibernateCallback() {
			public Object doInHibernate(Session session) throws HibernateException, SQLException {
				List<Integer> result = new ArrayList<Integer>(0);
				if (paramsList != null)
					for (int i = 0; i < paramsList.size(); i++) {
						Query query = session.createSQLQuery(sql);
						List<?> params = paramsList.get(i);
						if (params != null)
							for (int j = 0; j < params.size(); j++)
								query.setParameter(j, params.get(j));
						result.add(query.executeUpdate());
					}
				return result;
			}
		});
	}
	
	/**
	 * hql获得分页数据
	 * 
	 * @param hql
	 * @param page
	 * @return
	 */
	public Page getPage(String hql,int pageSize,int currentPageNo){
		return getPage(hql,null,pageSize,currentPageNo);
	}
	
	/**
	 * hql获得分页数据
	 * 
	 * @param hql
	 * @param params
	 * @param page
	 * @return
	 */
	public Page getPage(String hql,List<?> params,int pageSize,int currentPageNo){
		Page page = new Page(pageSize,currentPageNo);
		page.count = count(hql);
		page.pageCount = page.count / pageSize;
		if(page.count % page.size != 0) page.pageCount++; 
		int firstResult = (page.current-1) * page.size;
		page.hasNext = page.current * page.size < page.count;
		page.hasPrevious = page.current > 1;
		page.items = this.find(hql, params, firstResult, page.size);
		return page;
	}
	
	/**
	 * 普通sql获得分页信息
	 * 
	 * @param sql
	 * @param page
	 * @return
	 */
	public Page getPageBySql(String sql,int pageSize,int currentPageNo){
		return getPageBySql(sql,null, pageSize, currentPageNo);
	}
	
	/**
	 * 普通sql获得分页信息
	 * 
	 * @param hql
	 * @param params
	 * @param page
	 * @return
	 */
	public Page getPageBySql(String sql,List<?> params,int pageSize,int currentPageNo){
		Page page = new Page(pageSize,currentPageNo);
		page.count = countBySql(sql);
		page.pageCount = page.count / page.size;
		if(page.count % page.size != 0) page.pageCount++; 
		int firstResult = (page.current-1) * page.size;
		page.hasNext = page.current * page.size < page.count;
		page.hasPrevious = page.current > 1;
		page.items = this.findBySql(sql, params, firstResult, page.size);
		return page;
	}
	
	/**
	 * 分页信息类
	 * @author serj
	 *
	 */
	public class Page{
		public int size = 20;//每页大小,防止内存溢出，最大限制100
		public int pageCount =1;//总页数  
		public int current = 1;//当前页值
		public int count = 0;//总记录数		
		public boolean hasNext = false;//有下一页
		public boolean hasPrevious = false;//有前一页
		public List<?> items = new ArrayList<Object>(0);//当前页内记录List

	    public int getSize() {
			return size;
		}

		public void setSize(int size) {
			this.size = size>100?100:size;//防止内存溢出，最大限制100
		}

		public int getPageCount() {
			return pageCount;
		}

		public void setPageCount(int pageCount) {
			this.pageCount = pageCount;
		}

		public int getCurrent() {
			return current;
		}

		public void setCurrent(int current) {
			this.current = current;
		}

		public int getCount() {
			return count;
		}

		public void setCount(int count) {
			this.count = count;
		}
		
		public boolean isHasNext() {
			return hasNext;
		}

		public void setHasNext(boolean hasNext) {
			this.hasNext = hasNext;
		}

		public boolean isHasPrevious() {
			return hasPrevious;
		}

		public void setHasPrevious(boolean hasPrevious) {
			this.hasPrevious = hasPrevious;
		}
		
		public List<?> getItems() {
			return items;
		}

		public void setItems(List<?> items) {
			this.items = items;
		}		

		public Page(int size,int current){
	    	this.size = size;
	    	this.current = current;
	    }
	}

}
